package cn.iocoder.yudao.module.trade.order.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.module.api.dine.DinePrintApi;
import cn.iocoder.yudao.module.api.dine.enums.DineStatusEnum;
import cn.iocoder.yudao.module.api.trade.order.enums.TradeOrderOperateTypeEnum;
import cn.iocoder.yudao.module.trade.order.bo.TradeOrderLogCreateBO;
import cn.iocoder.yudao.module.trade.order.dal.dataobject.TradeOrderDO;
import cn.iocoder.yudao.module.trade.order.dal.dataobject.TradeOrderLogDO;
import cn.iocoder.yudao.module.trade.order.dal.mysql.TradeOrderMapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserType;

/**
 * <pre>
 * OOoO0OOoO0OOOooo0oOOOO0OOOOO0oooOO0ooOOO0Ooooo0OOOOo0ooooO0OOooo0Ooooo0OOOOO
 *  这里是文件说明
 * OOoO0OOoO0OOOooo0oOOOO0OOOOO0oooOO0ooOOO0Ooooo0OOOOo0ooooO0OOooo0Ooooo0OOOOO
 * </pre>
 *
 * @author 山野羡民（1032694760@qq.com）
 * @since 2025/08/28
 */
@Slf4j
@Service
public class TradeOrderAcceptService {
    @Resource
    private TradeOrderMapper tradeOrderMapper;

    @Resource
    @Lazy // 延迟加载，避免循环依赖
    private TradeOrderLogService tradeOrderLogService;

    @Resource
    @Lazy // 延迟加载，避免循环依赖
    private DinePrintApi dinePrintApi;

    @Transactional(rollbackFor = Exception.class)
    public int autoAcceptOrder() {
        // 查询待接收的订单 TODO 接单超时的情况后续再考虑如何处理
        List<TradeOrderDO> acceptableOrders = tradeOrderMapper.selectAcceptableList();
        if (CollUtil.isEmpty(acceptableOrders)) {
            log.debug("[autoAcceptOrder][查询到没有待接收的订单数量为 0]");
            return 0;
        }
        int count = 0;
        Set<String> tradeNos = acceptableOrders.stream().map(TradeOrderDO::getNo).collect(Collectors.toSet());
        Map<String, Boolean> printSuccessMap = dinePrintApi.getPrintSuccessMap(tradeNos);
        for (TradeOrderDO acceptableOrder : acceptableOrders) {
            if (Boolean.TRUE.equals(printSuccessMap.getOrDefault(acceptableOrder.getNo(), false))) {
                log.debug("[autoAcceptOrder][订单({})的小票打印成功视为接单]", acceptableOrder.getNo());
                TradeOrderDO acceptedOrder = new TradeOrderDO();
                acceptedOrder.setId(acceptableOrder.getId());
                acceptedOrder.setDineStatus(DineStatusEnum.ACCEPTED.getValue());
                acceptedOrder.setAcceptedTime(LocalDateTime.now());
                int result = tradeOrderMapper.updateById(acceptedOrder);
                if (result > 0) {
                    saveTradeOrderLog(acceptedOrder);
                    count++;
                }
            }
        }
        return count;
    }

    @Transactional(rollbackFor = Exception.class)
    public boolean acceptOrderWhenPrintSuccess(String tradeNo) {
        TradeOrderDO tradeOrder = tradeOrderMapper.selectByNo(tradeNo);
        if (tradeOrder == null) {
            return false;
        }
        TradeOrderDO updateObj = new TradeOrderDO();
        updateObj.setId(tradeOrder.getId());
        updateObj.setDineStatus(DineStatusEnum.ACCEPTED.getValue());
        updateObj.setAcceptedTime(LocalDateTime.now());
        int result = tradeOrderMapper.updateById(updateObj);
        if (result > 0) {
            saveTradeOrderLog(updateObj);
        }
        return true;
    }

    private void saveTradeOrderLog(TradeOrderDO order) {
        try {
            Integer userType = ObjectUtil.defaultIfNull(getLoginUserType(), TradeOrderLogDO.USER_TYPE_SYSTEM);
            Long userId = ObjectUtil.defaultIfNull(getLoginUserId(), TradeOrderLogDO.USER_ID_SYSTEM);
            String content = StrUtil.format(TradeOrderOperateTypeEnum.SYSTEM_ACCEPT.getContent(), Map.of());
            TradeOrderLogCreateBO createBO = new TradeOrderLogCreateBO();
            createBO.setUserId(userId);
            createBO.setUserType(userType);
            createBO.setOrderId(order.getId());
            createBO.setBeforeStatus(order.getStatus());
            createBO.setAfterStatus(order.getStatus());
            createBO.setOperateType(TradeOrderOperateTypeEnum.SYSTEM_ACCEPT.getType());
            createBO.setContent(content);
            tradeOrderLogService.createOrderLog(createBO);
        } catch (Exception e) {
            log.error("[saveTradeOrderLog][订单({})接单日志记录出错]", order.getId(), e);
        }
    }

}
